package com.czl.websocket.server;

import cn.hutool.json.JSONUtil;
import com.czl.websocket.bean.Message;
import com.czl.websocket.bean.User;
import com.czl.websocket.type.MessageType;
import org.java_websocket.WebSocket;
import org.java_websocket.enums.ReadyState;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 石雷
 * shilei1@jiayuan.com
 * 2021/1/22/022 15:10
 */
public class WebSockeManger {
    //心跳周期 毫秒
    static final int heartbeatCycle = 2*1000;

    private static List<WebSocket> WebSocketList=new ArrayList<WebSocket>();
    private static Map<WebSocket,String> WebSocketUid=new HashMap<WebSocket, String>();
    private static Map<String,WebSocket> UidWebSocket=new HashMap();
    private static final Map<WebSocket,Long> AliveListTime=new HashMap<>();

    /**
     * 登记在线用户和连接
     * @param webSocket
     * @param uid
     */
    public static synchronized void add(WebSocket webSocket,String uid){
        alive(webSocket);
        WebSocketList.add(webSocket);
        if(uid!=null){
            WebSocketUid.put(webSocket,uid);
            UidWebSocket.put(uid,webSocket);
        }
    }

    public static List<WebSocket> getWebSocketList() {
        return WebSocketList;
    }

    /**
     * 移除在线连接和用户
     * @param webSocket
     */
    public static synchronized void remove(WebSocket webSocket){
        String uid = WebSocketUid.get(webSocket);
        System.out.println(uid+"心跳超时 客户端已退出");
        if(webSocket!=null){
            webSocket.close();
        }
        WebSocketList.remove(webSocket);
        if(uid!=null){
            UidWebSocket.remove(uid);
        }
        WebSocketUid.remove(webSocket);
    }

    /**
     * 获取对应连接登记的uid
     * @param webSocket
     * @return
     */
    public static String getUid(WebSocket webSocket){
        return  WebSocketUid.get(webSocket);
    }

    public static WebSocket getWebSocketByUid(String uid){
        return  UidWebSocket.get(uid);
    }

    /**
     * 标记心跳最后时间
     * @param webSocket
     */
    public static void alive(WebSocket webSocket){
        AliveListTime.put(webSocket,new Date().getTime());
        System.out.println("===alive==  "+"uid:"+WebSocketUid.get(webSocket) + "|time:"+new Date().getTime()+"|在线人数:"+WebSocketList.size());
    }

    /**
     * 根据心跳判断存活状态客户端 移除非存活客户端连接
     */
    public static void aliveCheck(){
        System.out.println("心跳检测开始");
        while(true){
            try {
                System.out.println("心跳进行中。。。。");
                List<WebSocket> unAliveList = WebSocketList.stream().filter(webSocket -> {
                            Long lastTime = AliveListTime.get(webSocket);
                            if (lastTime == null || new Date().getTime() - lastTime > heartbeatCycle * 5) {
                                System.out.println("===!!!!=="+new Date().getTime()+"="+lastTime);
                                return true;
                            }
                            return false;
                        }
                ).collect(Collectors.toList());

                for (WebSocket webSocket : unAliveList) {remove(webSocket);}

                Thread.sleep(heartbeatCycle*5);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("心跳检测发生异常");
            }
        }



    }

        public static String send(String fromUid, String uid, MessageType messageType,String text){
            WebSocket webSocket = UidWebSocket.get(uid);
            Message message = new Message();
            message.setUser(UserService.getUserInfo(uid));
            message.setFromUid(fromUid);
            message.setText(text);
            message.setType(messageType.getCode());

            for (int i = 0; i < 20; i++) {
                if (webSocket.getReadyState().equals(ReadyState.OPEN)) {
                    break;
                }
            }
            webSocket.send(JSONUtil.toJsonStr(message));
            return null;
        }


}
